import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class UnValueMetric {
    public void unValueMetrc(JSONArray jsonArrayCells, List<Packages> packages, Metric metrics[], AllMetric allMetric) {
        // 记录src/dest所属包
        int srcNum, destNum, srcPackageNum, destPackageNum;
        System.out.println("计算中...");

        // 不加权计算
        for (int i = 0; i < jsonArrayCells.length(); i++) {
            //System.out.println("遍历第" + (i + 1) + "个values");
            JSONObject cell = (JSONObject) jsonArrayCells.get(i);
            JSONObject values = cell.getJSONObject("values");

            srcNum = cell.getInt("src");
            destNum = cell.getInt("dest");
            srcPackageNum = (new PackageNum()).packageNum(srcNum, packages);
            destPackageNum = (new PackageNum()).packageNum(destNum, packages);

            // 存在调用call
            if (values.has("Call")) {
                allMetric.usesSum++;
                metrics[srcPackageNum].packageUsesSum++;
                if (srcPackageNum != destPackageNum) {
                    allMetric.difUsesSum++;
                    metrics[srcPackageNum].difPackageUsesSum++;
                    //metrics[srcPackageNum].difPackageClientSP++;  // 包更改影响指数
                    if (!metrics[srcPackageNum].difPackageUsesP.contains(destPackageNum)) {
                        metrics[srcPackageNum].difPackageUsesP.add(destPackageNum);
                        metrics[srcPackageNum].difPackageUsesPNum++;
                    }

                    // 内聚度指标记录 P的客户包、提供者包
                    if (!metrics[destPackageNum].packageClientsP.contains(srcPackageNum)) {
                        metrics[destPackageNum].packageClientsP.add(srcPackageNum);
                    }
                    if (!metrics[srcPackageNum].packageProviderP.contains(destPackageNum)) {
                        metrics[srcPackageNum].packageProviderP.add(destPackageNum);
                    }
                }
            }
            // 存在扩展使用 出现extend/implement
            if (values.has("Extend") || values.has("Implement")) {
                allMetric.extSum++;
                metrics[destPackageNum].packageExtSum++;
                if (srcPackageNum != destPackageNum) {
                    allMetric.difExtSum++;
                    metrics[destPackageNum].difPackageExtSum++;
                    //metrics[destPackageNum].difPackageClientSP++;  //包更改影响指数
                    if (!metrics[destPackageNum].difPackageExtP.contains(srcPackageNum)) {
                        metrics[destPackageNum].difPackageExtP.add(srcPackageNum);
                        metrics[destPackageNum].difPackageExtPNum++;
                    }

                    // 内聚度指标记录 P的客户包、提供者包
                    if (!metrics[destPackageNum].packageClientsP.contains(srcPackageNum)) {
                        metrics[destPackageNum].packageClientsP.add(srcPackageNum);
                    }
                    if (!metrics[srcPackageNum].packageProviderP.contains(destPackageNum)) {
                        metrics[srcPackageNum].packageProviderP.add(destPackageNum);
                    }
                }
            }
        }

        // 第二次遍历 计算P的输入接口
        System.out.println("第二遍遍历");
        for (int i = 0; i < jsonArrayCells.length(); i++) {
            JSONObject cell = (JSONObject) jsonArrayCells.get(i);
            JSONObject values = cell.getJSONObject("values");

            srcNum = cell.getInt("src");
            destNum = cell.getInt("dest");
            srcPackageNum = (new PackageNum()).packageNum(srcNum, packages);
            destPackageNum = (new PackageNum()).packageNum(destNum, packages);

            // 存在调用call
            if (values.has("Call") || values.has("Extend") || values.has("Implement")) {
                if (srcPackageNum != destPackageNum) {
                    // 内聚度指标记录
                    if (!metrics[srcPackageNum].packageInIntC.contains(srcNum) && metrics[srcPackageNum].packageClientsP.contains(destPackageNum)) {
                        metrics[srcPackageNum].packageInIntC.add(srcNum);
                    }
                }
            }
        }

        // 第三次遍历 计算P的RoleClientsSum， 统计包P的 提供不
        System.out.println("第三遍遍历");
        for (int i = 0; i < jsonArrayCells.length(); i++) {
            JSONObject cell = (JSONObject) jsonArrayCells.get(i);
            JSONObject values = cell.getJSONObject("values");

            srcNum = cell.getInt("src");
            destNum = cell.getInt("dest");
            srcPackageNum = (new PackageNum()).packageNum(srcNum, packages);
            destPackageNum = (new PackageNum()).packageNum(destNum, packages);

            // 存在调用call
            if (values.has("Call") || values.has("Extend") || values.has("Implement")) {
                if (srcPackageNum != destPackageNum) {
                    // 内聚度指标记录
                    // 包目标集中指数计算 计算InIntPQ, RoleClientsSum
                    if (metrics[destPackageNum].packageInIntC.contains(destNum)) {
                        int leap = 1; // 设置标志变量
                        for (InIntPC inIntPC : metrics[destPackageNum].inIntPC) { // 检查是否已经存储过InIntPQ
                            if (inIntPC.classNum == destNum && inIntPC.packageNum == srcPackageNum) {
                                leap = 0; // 如果找到，将leap置0
                                break;
                            }
                        }
                        if (leap == 1) {
                            InIntPC inIntPC = new InIntPC();
                            inIntPC.packageNum = srcPackageNum;
                            inIntPC.classNum = destNum;
                            metrics[destPackageNum].inIntPC.add(inIntPC);
                            metrics[destPackageNum].RoleClientsSum++;

                            if (metrics[destPackageNum].providerCSPQ.containsKey(destPackageNum)) {
                                metrics[destPackageNum].providerCSPQ.put(destPackageNum, metrics[destPackageNum].providerCSPQ.get(destPackageNum) + destNum);
                            } else {
                                metrics[destPackageNum].providerCSPQ.put(srcPackageNum, destNum + "");
                            }
                        }
                    }
                }
            }
        }
    }
}
